#include <clusnet/base/FixedMemoryPool.h>
#include <gtest/gtest.h>
#include <clusnet/base/Timestamp.h>

#include <vector>

using namespace clusnet::base;

TEST(FixedMemoryPoolAcquire, Test_acquire)
{
    // default 1024
    FixedMemoryPool<> pool;
    char* p = static_cast<char*>(pool.acquire());
    char* cur = p;
    *cur++ = 'h';
    *cur++ = 'e';
    *cur++ = 'l';
    *cur++ = 'l';
    *cur++ = 'o';
    ASSERT_STREQ(p, "hello");
    pool.release(p);
}

void testBigBlock(size_t count)
{
    std::vector<void*> vec;
    Timestamp start(Timestamp::now());
    FixedMemoryPool<1024*1024> pool;    // 1M
    for (size_t i = 0; i < count; ++i)
    {
        vec.push_back(pool.acquire());
    }
    for (auto& elem : vec)
    {
        pool.release(elem);
    }
    std::cout << "process " << count << " counts, total " << 1024 * 1024 * count << " bytes, spend " << timeDifference(Timestamp::now(), start) * 1000000 << " us" << std::endl;
}

void testBench(size_t count)
{
    std::vector<void *> vec;
    Timestamp start(Timestamp::now());
    FixedMemoryPool<> pool;
    for (size_t i = 0; i < count; ++i)
    {
        vec.push_back(pool.acquire());
    }
    Timestamp acquire(Timestamp::now());
    std::cout << "process acquire " << count << " counts, total " << 1024 * count << " bytes, spend " << timeDifference(acquire, start) * 1000 << " ms" << std::endl;
    for (auto& elem : vec)
    {
        pool.release(elem);
    }
    Timestamp release(Timestamp::now());
    std::cout << "process release " << count << " counts, spend " << timeDifference(release, acquire) * 1000 << " ms" << std::endl;
}

int main(int argc, char* argv[])
{
    testBigBlock(512);      // 512M
    testBench(1024 * 1024); // 1G
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
